Skip to content

Comments

fix: harden wasm image pipeline with safe errors, input sanitization, and test coverage#3

Merged
2YH02 merged 5 commits intomainfrom
develop
Feb 12, 2026
Merged

fix: harden wasm image pipeline with safe errors, input sanitization, and test coverage#3
2YH02 merged 5 commits intomainfrom
develop

Conversation

@2YH02
Copy link
Owner

@2YH02 2YH02 commented Feb 12, 2026

Summary

  • What changed?
    • Hardened the Rust/TS image pipeline with safer option sanitization, unified defaults, and safer error handling.
    • Added/expanded Rust tests for resize pipeline behavior and error paths.
    • Updated docs to reflect default values, non-finite input sanitization, and error handling policy.
    • Added AGENTS.md contributor/agent guidance.
  • Why was this change needed?
    • To make runtime behavior more predictable and safe in browser contexts.
    • To prevent leaking low-level internal errors to API consumers.
    • To align defaults and validation behavior between Rust WASM core and TS wrapper.

Key Changes

  • Introduced typed internal error flow in src/lib.rs, while keeping user-facing messages generic/safe.
  • Sanitized non-finite numeric inputs (NaN, Infinity) in TS wrapper clamping and aligned quality default to 0.7.
  • Expanded Rust test coverage for resize behavior, decode failure paths, and WebP/error scenarios.

Breaking Changes

  • No breaking changes
  • Yes (describe below)

Validation

  • cargo test
  • npm run build
  • Example app manual check

Release Checklist (if applicable)

  • package.json version is correct
  • CHANGELOG.md updated
  • develop -> main merge ready
  • Tag push plan ready (e.g. v2.1.0)

Notes

  • Error message text exposed to users is now intentionally more generic; consumers should not rely on previous detailed error strings.
  • This PR includes AGENTS.md (repo workflow guidance) in addition to runtime code/test/docs changes.
  • If npm publish is planned after merge, set version/changelog/tag in a follow-up release prep step.

@qodo-code-review
Copy link

Review Summary by Qodo

Harden WASM pipeline with tests, docs, and input validation

🐞 Bug fix 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• Added three Rust tests covering no-dimension, decode-failure, and WebP encoding paths
• Documented default values, non-finite input sanitization, and error handling policy
• Added AGENTS.md contributor guidance for project workflow and working rules
• Clarified quality parameter defaults to 0.7 with NaN/Infinity sanitization
Diagram
flowchart LR
  A["Rust Core<br/>lib.rs"] -->|"3 new tests"| B["Test Coverage<br/>no-dim, decode, webp"]
  C["README.MD"] -->|"clarify defaults<br/>& validation"| D["User-facing Docs"]
  E["AGENTS.md<br/>new file"] -->|"contributor<br/>guidance"| F["Developer Workflow"]
  A -->|"sanitize NaN<br/>Infinity"| G["Safe Input<br/>Handling"]
Loading

Grey Divider

File Changes

1. src/lib.rs 🧪 Tests +54/-0

Add Rust tests for resize edge cases

• Added three new Rust unit tests: resize_image_without_dimensions_keeps_original_size,
 resize_image_returns_decode_error_for_invalid_input_bytes, and resize_image_encodes_as_webp
• Tests cover edge cases: omitted dimensions, invalid input bytes, and WebP format encoding
• Validates core pipeline behavior for no-op resize, error paths, and format conversion

src/lib.rs


2. README.MD 📝 Documentation +23/-4

Document defaults, validation, and error policy

• Added two new sections: "Defaults and Input Validation" and "Error Handling Policy"
• Updated quality parameter documentation to specify 0.7 default and NaN/Infinity sanitization
• Updated brightness parameter to document 0.5 default and non-finite value handling
• Clarified that non-finite values are sanitized to safe defaults across all numeric options

README.MD


3. AGENTS.md 📝 Documentation +29/-0

Add contributor and agent workflow guidance

• New file providing contributor and agent guidance for the project
• Documents key files, common build commands, and working rules
• Establishes API compatibility expectations, error safety policy, and validation requirements
• Specifies format support preservation and change scope guidelines

AGENTS.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Feb 12, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

✅ 1. Brittle decode-error test 🐞 Bug ⛯ Reliability
Description
The new test asserts invalid bytes must return ToolkitError::DecodeFailed, but the implementation
can also fail earlier in with_guessed_format() and return ToolkitError::FormatGuessFailed. This
can cause the test to fail consistently (and block CI) depending on where the pipeline errors for
that input.
Code

src/lib.rs[R378-392]

+    #[test]
+    fn resize_image_returns_decode_error_for_invalid_input_bytes() {
+        let input = vec![0x00, 0x11, 0x22, 0x33];
+        let options = ResizeOptions {
+            width: Some(32),
+            height: Some(32),
+            quality: None,
+            format: "jpg".to_string(),
+            brightness: 0.5,
+            resampling: 4,
+        };
+
+        let err = resize_image_with_options(&input, options).unwrap_err();
+        assert!(matches!(err, ToolkitError::DecodeFailed(_)));
+    }
Evidence
resize_image_with_options maps errors from with_guessed_format() to FormatGuessFailed and
errors from decode() to DecodeFailed, so asserting only DecodeFailed is too strict for
arbitrary invalid bytes.

src/lib.rs[103-111]
src/lib.rs[378-392]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new unit test assumes arbitrary invalid bytes always fail during `decode()` and return `ToolkitError::DecodeFailed(_)`, but the pipeline can also fail earlier during `with_guessed_format()`.
### Issue Context
`resize_image_with_options` has two distinct fallible stages for input parsing:
- `with_guessed_format()` -&amp;amp;gt; `ToolkitError::FormatGuessFailed`
- `decode()` -&amp;amp;gt; `ToolkitError::DecodeFailed`
### Fix Focus Areas
- src/lib.rs[378-392]
### Suggested change
Option A (simplest):
- Update the test assertion to accept either error variant.
Option B (more specific):
- Replace `input` with bytes that are likely to pass format guessing (e.g., a truncated PNG/JPEG header) but still fail decode, then keep asserting `DecodeFailed(_)`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

✅ 2. Brightness docs/type mismatch 🐞 Bug ✓ Correctness
Description
README now documents BrightnessOptions.brightness as defaulting to 0.5 when omitted, but the
public TS type requires brightness, so TS users cannot omit it without a type error. This is a
confusing mismatch between docs and the typed API surface.
Code

README.MD[R121-126]

### `BrightnessOptions`
| Option       | Type   | Description                                         |
| ------------ | ------ | --------------------------------------------------- |
-| `brightness` | number | 0.0 to 1.0                                          |
+| `brightness` | number | 0.0 to 1.0. Defaults to `0.5`. Non-finite values are sanitized to the default. |
| `quality`    | number | (Optional) 0.0 to 1.0. Effective if source is JPEG. |
Evidence
The README explicitly states a default for BrightnessOptions.brightness, implying it can be
omitted, while the TypeScript type makes it required and adjustBrightness takes that required
type.

README.MD[121-126]
ts-wrapper/resizeImage.ts[37-43]
ts-wrapper/resizeImage.ts[83-92]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
README claims `BrightnessOptions.brightness` defaults to `0.5` when omitted, but the TS type currently requires `brightness`, creating a docs vs typed-API mismatch.
### Issue Context
Runtime defaulting exists via `processWithWasm` sanitization, but TS users are blocked from omitting `brightness` due to the required type.
### Fix Focus Areas
- README.MD[121-126]
- ts-wrapper/resizeImage.ts[37-43]
- ts-wrapper/resizeImage.ts[83-92]
### Suggested change
Choose one:
1) Align types to docs:
- Change `BrightnessOptions` to `brightness?: number` and (optionally) add JSDoc noting the default.
2) Align docs to types:
- Update README to state `brightness` is required for `adjustBrightness`, and keep defaulting language in the general defaults section (or scoped to `ProcessImageOptions`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@2YH02 2YH02 merged commit 1488ecd into main Feb 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant